﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using MYEXCEL = Microsoft.Office.Interop;
using System.Collections;
using System.Reflection;    //引用这个才能使用Missing字段
using System.Data.OleDb;
using System.Runtime.InteropServices;
using System.IO.Ports;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
using System.Threading;
using SerialCommunication;
using MyClass;

namespace GPS_DB
{
    public partial class Form_DataBaseSVR : Form
    {
        public SerialFrame myport = new SerialFrame();
        public SimulationData mydata = new SimulationData();
        public GPS_CMD myframe = new GPS_CMD();
        public GpsMapImg gpsI = new GpsMapImg();
        public bool AutoSelectLine = true;
        bool CatchStart;
        Point DownPoint = Point.Empty;
        int mouselon, mouselat;
        int writeRow, writeDisRow, writeQieHuan;

        string[] myFilePath = new string[5];


        #region MainWindow
        public Form_DataBaseSVR()
        {
            InitializeComponent();

            this.pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            FindPort();
            PortRxd_Timer.Enabled = true;
        }

        private void Form_DataBaseSVR_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 5; i++)
            {
                myFilePath[i] = LrnS.GetItem("latestDbPath" + i.ToString());
            }
            reNew_tSMI_F_LatestDB();

        }

        private void Form_DataBaseSVR_Shown(object sender, EventArgs e)
        {
        }

        private void Form_DataBaseSVR_FormClosing(object sender, FormClosingEventArgs e)
        {
            LrnS.SaveItem("GPSImgDivisorSaving", gpsI.Divisor.ToString());
            LrnS.SaveItem("CenterLonValueSaving", gpsI.CenterLon.ToString());
            LrnS.SaveItem("CenterLatValueSaving", gpsI.CenterLat.ToString());
        }

        #endregion

        #region toolStrip Port
        private void tS_PortOpen_Click(object sender, EventArgs e)
        {
            if (myport.IsOpen())
            {
                try
                {
                    myport.ClosePort();
                    tS_PortSelect.Enabled = true;
                    tS_PortOpen.Image = Properties.Resources.Play;
                    ts_AutoConnect.Enabled = true;
                }
                catch { }
            }
            else
            {
                try
                {
                    myport.OpenPort(tS_PortSelect.Text);
                    tS_PortSelect.Enabled = false;
                    tS_PortOpen.Image = Properties.Resources.Stop;
                    ts_AutoConnect.Enabled = false;

                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    tS_PortSelect.Enabled = true;
                    tS_PortOpen.Image = Properties.Resources.Play;
                    ts_AutoConnect.Enabled = true;
                }
            }
        }

        private void tS_PortSelect_DropDown(object sender, EventArgs e)
        {
            FindPort();
        }

        private void ts_AutoConnect_Click(object sender, EventArgs e)
        {
            FindPort();
            bool portFound = false;
            this.pictureBox1.Focus();
            tS_PortOpen.Enabled = false;
            string[] ports = SerialPort.GetPortNames();
            for (int i = 0; i < ports.Length; i++)
            {
                try
                {
                    tS_PortSelect.Text = ports[i];
                    myport.OpenPort(ports[i]);
                    myframe.CmdHistory.Clear();

                    byte[] data = new byte[1];
                    data[0] = 0x01;
                    myport.SendCmd(0x02, 0xa4, data, 0, 1);

                    int last_start;
                    last_start = Environment.TickCount;
                    while ((Environment.TickCount - last_start) <= 500)
                    {
                        Application.DoEvents();
                        if (myframe.CmdHistory.Count > 0)
                        {
                            portFound = true;
                            break;
                        }
                    }
                    if (portFound)
                    {
                        tS_PortOpen.Text = "关闭";
                        tS_PortSelect.Enabled = false;
                        tS_PortOpen.Image = Properties.Resources.Stop;
                        ts_AutoConnect.Enabled = false;
                        break;
                    }
                    else
                    {
                        myport.ClosePort();
                    }
                }
                catch (Exception)
                {
                }
                
            }
            tS_PortOpen.Enabled = true;
        }

        private void FindPort()
        {
            tS_PortSelect.DropDownStyle = ComboBoxStyle.DropDownList;
            tS_PortSelect.Items.Clear();
            string[] ports = SerialPort.GetPortNames();
            if (ports != null)
            {
                for (int i = 0; i < ports.Length; i++)
                {
                    tS_PortSelect.Items.Add(ports[i]);
                }
            }
            if (tS_PortSelect.Items.Count > 0)
            {
                tS_PortSelect.SelectedIndex = 0;
            }
        }
        #endregion

        #region Form Control[Button]
        private void button_decelerate_Click(object sender, EventArgs e)
        {
            if (TrainRun_Timer.Interval < 1000)
            {
                TrainRun_Timer.Interval += 100;
                labelSpeed.Text = "速度：" + ((float)1000 / TrainRun_Timer.Interval).ToString("0.0");
                button_accelerate.Enabled = true;
                if (TrainRun_Timer.Interval >= 1000)
                    button_decelerate.Enabled = false;
            }
        }

        private void button_accelerate_Click(object sender, EventArgs e)
        {
            int minItvl = 200;
            if (TrainRun_Timer.Interval > minItvl)
            {
                TrainRun_Timer.Interval -= 100;
                labelSpeed.Text = "速度：" + ((float)1000 / TrainRun_Timer.Interval).ToString("0.0");
                button_decelerate.Enabled = true;
                if (TrainRun_Timer.Interval <= minItvl)
                    button_accelerate.Enabled = false;
            }
        }
        #endregion

        #region Tiemr Tick

        private void TrainRun_Timer_Tick(object sender, EventArgs e)
        {
            #region Send New GPS Data
            if (!mydata.NewNextTestPoint())
            {
                TrainRun_Timer.Enabled = false;
                if (!mydata.NextTestFile())
                {
                    StopSimulation();
                }
                else
                {
                    myport.SendCmd(0x02, 0xa3, null, 0, 0);
                    Delay(5000);
                    mydata.SetRecFileName();
                    gpsI.ReadInSimulationFile((mydata.CurrentSimulationFile()));

                    string rdname = Path.GetFileNameWithoutExtension(mydata.CurrentSimulationFile());
                    rdname = GF.GetLineName(rdname);
                    gpsI.FocusOnRoad(rdname, false);

                    myport.SendCmd(0x02, 0xa1, null, 0, 0);
                    TrainRun_Timer.Enabled = true;
                }
                return;
            }
            if (mydata.CurrentDataValid())
            {
                SetGpsTXData(mydata.CurLon, mydata.CurLat);
            }
            else
            {
                SendVGpsData();
            }
            #endregion

            #region Image Handling
            labelState.Text = mydata.RoadDataIndex.ToString() + ":" + mydata.RoadDataNumber.ToString() + "\r\n"
                              + "[" + mydata.FileIndex.ToString() + "/" + mydata.FileNames.Count.ToString() + "]\r\n"
                              + Path.GetFileNameWithoutExtension((string)mydata.FileNames[mydata.FileIndex - 1]);
            if (!mydata.CurrentDataValid())
            {
                gpsI.TrainImgSetColor(Color.Silver);
            }
            else
            {
                gpsI.TrainImgSetColor(Color.Fuchsia);
                gpsI.Train_lon = (int)mydata.CurLon * 10;
                gpsI.Train_lat = (int)mydata.CurLat * 10;   
            }
            if (!CatchStart)
            {
                DisplayMap();
                pictureBox1.Update();
            }
            #endregion

            #region Next GPS Data
            mydata.DataPointerInc();
            #endregion
        }

        private void PortRxd_Timer_Tick(object sender, EventArgs e)
        {
            while (!myport.IsEmpty())
            {
                RecFrameHnadler();
                myport.RecTailIncrese();
                readEvent.Set();
            }
        }

        #endregion

        #region pictureBox1 Event
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            this.pictureBox1.Focus();
            if (e.Button == MouseButtons.Right)
            {
                Clipboard.SetText(label_longitude.Text + "M" + label_latitude.Text);
                if (mydata.IsManual)
                {
                    int lon = GF.ToDimiDegree(label_longitude.Text.Trim());
                    int lat = GF.ToDimiDegree(label_latitude.Text.Trim());
                    mydata.SetTestSec((long)lon, (long)lat);
                }
            }
            
            if (!CatchStart)
            {
                CatchStart = true;
                DownPoint = new Point(e.X, e.Y);
                if (!tSMI_V_AutoShow.Checked)
                    pictureBox1.Cursor = Cursors.Hand;
                else
                    pictureBox1.Cursor = Cursors.No;
            }
        }

        private void pictureBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            string msg;
            int lon = (e.X - pictureBox1.Size.Width / 2) * gpsI.Divisor + gpsI.CenterLon;
            int lat = (pictureBox1.Size.Height / 2 - e.Y) * gpsI.Divisor + gpsI.CenterLat;
            msg = gpsI.SearchDB(lon, lat);
            labelState.Text = msg;

            if (msg.Contains("区间"))
                msg = msg.Substring(0, msg.IndexOf("区间"));

            if (msg.StartsWith("车站:\r\n"))
            {
                msg = msg.Substring(5);
                if(msg.Length == msg.IndexOf("\n")+1)
                    gpsI.FocusOnRoad(msg.Substring(0, msg.IndexOf('　')), false);
            }
            
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (CatchStart)
            {
                int width = Math.Abs(e.X - DownPoint.X);
                int height = Math.Abs(e.Y - DownPoint.Y);

                if (e.X < DownPoint.X)
                    width = -width;
                if (e.Y < DownPoint.Y)
                    height = -height;
                if (!tSMI_V_AutoShow.Checked)
                {
                    Graphics h = this.pictureBox1.CreateGraphics();
                    h.DrawImage(gpsI.GPS_DB_IMG, new Point((pictureBox1.Size.Width - gpsI.ImgWidth) / 2 + width,
                        (pictureBox1.Size.Height - gpsI.ImgHeight) / 2 + height));
                    DisplayTrain(width, height);
                    h.Dispose();
                }
            }
            else
            {
                mouselon = (e.X - pictureBox1.Size.Width / 2) * gpsI.Divisor + gpsI.CenterLon;
                mouselat = (pictureBox1.Size.Height / 2 - e.Y) * gpsI.Divisor + gpsI.CenterLat;
                mouselon = mouselon / 1000000 * 1000000 + (mouselon % 1000000) * 6 / 10;
                mouselat = mouselat / 1000000 * 1000000 + (mouselat % 1000000) * 6 / 10;
                label_longitude.Text = (mouselon / 10000).ToString() + "." + (mouselon % 10000).ToString().PadLeft(4, '0');
                label_latitude.Text = (mouselat / 10000).ToString() + "." + (mouselat % 10000).ToString().PadLeft(4, '0');
                if (mydata.IsManual)
                {
                    pictureBox1.Cursor = Cursors.NoMove2D;
                }
                else
                {
                    pictureBox1.Cursor = Cursors.Default;
                }
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (CatchStart)
            {
                CatchStart = false;
                pictureBox1.Cursor = Cursors.Default;

                int width = Math.Abs(e.X - DownPoint.X);
                int height = Math.Abs(e.Y - DownPoint.Y);

                if (e.X > DownPoint.X)
                    width = -width;
                if (e.Y < DownPoint.Y)
                    height = -height;
                if (!tSMI_V_AutoShow.Checked)
                {
                    gpsI.CenterLon += width * gpsI.Divisor;
                    gpsI.CenterLat += height * gpsI.Divisor;
                    gpsI.CreatGPS_DB_IMG();
                    DisplayMap();
                }
            }
        }

        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            int i;
            int tmp = gpsI.Divisor;
            for (i = 0; i < Math.Abs(e.Delta); i = i + 120)
            {
                if (e.Delta > 0)
                    tmp = tmp - tmp / 3 + 5;
                else
                    tmp = tmp + tmp / 3 + 3;
            }
            if (!tSMI_V_AutoShow.Checked)
            {
                int x, y;
                x = (e.X - pictureBox1.Size.Width / 2) * gpsI.Divisor + gpsI.CenterLon;
                y = (pictureBox1.Size.Height / 2 - e.Y) * gpsI.Divisor + gpsI.CenterLat;

                gpsI.Zoom(new Point(x, y), tmp, true);
                gpsI.Divisor = tmp;
                gpsI.CreatGPS_DB_IMG();
                DisplayMap();
            }
        }

        private void pictureBox1_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
                return;
            if (!groupBoxMap.Enabled)
                return;
            gpsI.GPS_DB_IMG_SizeChange(pictureBox1.Size.Width + 500, pictureBox1.Size.Height + 300);
            DisplayMap();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (!groupBoxMap.Enabled)
                return;
            Graphics hh = e.Graphics;
            hh.DrawImage(gpsI.GPS_DB_IMG, new Point((pictureBox1.Size.Width - gpsI.ImgWidth) / 2,
                (pictureBox1.Size.Height - gpsI.ImgHeight) / 2));
            pictureBox1.Focus();
        }
        #endregion

        #region Menu Events

        private void tSMI_CurrentStation_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue != 13)
                return;
            if (!gpsI.ViewStaion(tSMI_CurrentStation.Text.Trim()))
            {
                MessageBox.Show("Can't find station: " + tSMI_CurrentStation.Text.Trim());
                return;
            }
            tSMI_IMAGE.HideDropDown();
            gpsI.CreatGPS_DB_IMG();
            pictureBox1.Invalidate();
        }

        private void tSMI_GIS_CreatXLS_Click(object sender, EventArgs e)
        {
            #region old
            /*
             * Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
             if (xlApp == null)
                 return false;


             xlApp.SheetsInNewWorkbook = 2;
           
             Microsoft.Office.Interop.Excel.Workbook xlBook = xlApp.Workbooks.Add(true);

             Microsoft.Office.Interop.Excel.Worksheet xlSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlBook.Worksheets[1];

             Microsoft.Office.Interop.Excel.Range range = xlSheet.get_Range(xlApp.Cells[1, 1], xlApp.Cells[10, 10]);
             range.MergeCells = true;
             xlApp.ActiveCell.FormulaR1C1 = "AAAA";
             xlApp.ActiveCell.Font.Size = 12;
             xlApp.ActiveCell.Font.Bold = true;
             xlApp.ActiveCell.HorizontalAlignment = Microsoft.Office.Interop.Excel.Constants.xlCenter;
             xlSheet.Name = "_abcd1";

             xlBook.Saved = true;
            xlBook.SaveCopyAs("D:\\a.xls");

              xlBook = xlApp.Workbooks.Add(true);

             xlSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlBook.Worksheets[1];

             Microsoft.Office.Interop.Excel.Range range2 = xlSheet.get_Range(xlApp.Cells[1, 1], xlApp.Cells[10, 10]);
             range2.MergeCells = true;
             xlApp.ActiveCell.FormulaR1C1 = "BBBB";
             xlApp.ActiveCell.Font.Size = 12;
             xlApp.ActiveCell.Font.Bold = true;
             xlApp.ActiveCell.HorizontalAlignment = Microsoft.Office.Interop.Excel.Constants.xlCenter;
             xlSheet.Name = "_abcd2";

             xlBook.Saved = true;
             xlBook.SaveCopyAs("D:\\a.xls");

             xlApp.Quit();
             GC.Collect();
            return true;
             * */
            #endregion

            MYEXCEL.Excel.Application myexcel = new MYEXCEL.Excel.ApplicationClass();
            MYEXCEL.Excel.Workbook xbook1 = myexcel.Workbooks.Add(true);
            object mo = Missing.Value;
            MYEXCEL.Excel.Worksheet xSheet1 = (MYEXCEL.Excel.Worksheet)xbook1.ActiveSheet;
            xSheet1.Name = "车站";
            MYEXCEL.Excel.Worksheet xSheet2 = (MYEXCEL.Excel.Worksheet)xbook1.Worksheets.Add(mo, xSheet1, 1, mo);
            xSheet2.Name = "线路调度区段1";
            MYEXCEL.Excel.Worksheet xSheet3 = (MYEXCEL.Excel.Worksheet)xbook1.Worksheets.Add(mo, xSheet2, 1, mo);
            xSheet3.Name = "切换点1";

            myexcel.Visible = false;
            string fileDir = Application.StartupPath + "\\DBExcel\\";
            if (!Directory.Exists(fileDir))
                Directory.CreateDirectory(fileDir);
            fileDir = fileDir + /*DateTime.Now.ToString("yyyyMMddHHmm") + */" GPS数据库_AutoCreat" + ".xls";
            if (File.Exists(fileDir))
            {
                File.Delete(fileDir);
            }
            xSheet1.Cells[1, 1] = "线路";
            xSheet1.Cells[1, 2] = "调度区段";
            xSheet1.Cells[1, 3] = "模式";
            xSheet1.Cells[1, 4] = "车站";
            xSheet1.Cells[1, 5] = "代码";
            xSheet1.Cells[1, 6] = "电话";
            xSheet1.Cells[1, 7] = "经度";
            xSheet1.Cells[1, 8] = "纬度";
            xSheet1.Cells[1, 9] = "属性";
            xSheet1.Cells[1, 10] = "左上";
            xSheet1.Cells[1, 11] = "左上";
            xSheet1.Cells[1, 12] = "右下";
            xSheet1.Cells[1, 13] = "右下";
            xSheet1.Cells[1, 14] = "左下";
            xSheet1.Cells[1, 15] = "左下";
            xSheet1.Cells[1, 16] = "右上";
            xSheet1.Cells[1, 17] = "右上";
            xSheet1.Cells[1, 18] = "前站1";
            xSheet1.Cells[1, 19] = "前站2";
            xSheet1.Cells[1, 20] = "前站3";
            xSheet1.Cells[1, 21] = "前站4";
            writeRow = 2;
            writeDisRow = 2;
            writeQieHuan = 2;
            int roadIndex = 0;

            bool xlsnew = false;
            OpenFileDialog openFile_mdb = new OpenFileDialog();
            openFile_mdb.Filter = "数据库(.mdb)|*.mdb";
            openFile_mdb.Title = "数据库生成--请选择上行数据库文件";
            openFile_mdb.Multiselect = true;
            openFile_mdb.InitialDirectory = LrnS.GetItem("mdbtodatabase");
            if (openFile_mdb.ShowDialog() == DialogResult.OK)
            {
                LrnS.SaveItem("mdbtodatabase", Path.GetDirectoryName(openFile_mdb.FileName));
                xlsnew = true;
                foreach (string filename in openFile_mdb.FileNames)
                {
                    string addressStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename;
                    OleDbConnection conn = new OleDbConnection(addressStr);
                    OleDbDataAdapter dscmd = new OleDbDataAdapter();
                    DataSet resultdataset = new DataSet();

                    string strselect = "Select 经度,信息点名称,纬度,公里标,所属线路名称,车站名称,信息点属性,所属线路代码,所属区段名称,工作模式,车站电话号码 From export Order By 序号 Asc";
                    OleDbCommand selectcommand = new OleDbCommand(strselect, conn);
                    selectcommand.CommandType = CommandType.Text;

                    try
                    {
                        conn.Open();

                        dscmd.SelectCommand = selectcommand;
                        int numrows = dscmd.Fill(resultdataset, "export");

                        if (numrows > 0)
                        {
                            toWriteInStation(xSheet1, roadIndex, resultdataset, numrows);
                            toWriteInDispatch(xSheet2, resultdataset, numrows);
                            toWriteInQieHuang(xSheet3, resultdataset, numrows);

                            roadIndex++;
                        }
                        else
                        {
                            MessageBox.Show("未找到有效数据！");
                        }
                    }
                    catch (Exception er)
                    {
                        MessageBox.Show(er.Message.ToString());
                    }
                    finally
                    {
                        conn.Close();
                        tSMI_GIS_CreatXLS.Text = roadIndex.ToString() + "/" + openFile_mdb.FileNames.Length;
                    }
                }
                MessageBox.Show("生成文件成功！");
                tSMI_GIS_CreatXLS.Text = "生成数据库";
            }
            xbook1.SaveAs(fileDir, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal,
                mo, mo, mo, mo, MYEXCEL.Excel.XlSaveAsAccessMode.xlNoChange, mo, mo, mo, mo, mo);
            xbook1 = null;
            xSheet1 = null;
            myexcel.Quit();
            System.Runtime.InteropServices.Marshal.ReleaseComObject((object)myexcel);
            System.GC.Collect();

            if (xlsnew)
                System.Diagnostics.Process.Start(fileDir);
        }

        private void tSMI_S_EXIT_Click(object sender, EventArgs e)
        {
            StopSimulation();
        }

        private void tSMI_S_Inquery_Click(object sender, EventArgs e)
        {
            myport.SendCmd(0x03, 0x4F, null, 0, 0);
        }

        private void tSMI_S_InqCode_Click(object sender, EventArgs e)
        {
            byte[] data = new byte[1];
            data[0] = 0x03;
            myport.SendCmd(0x02, 0xa4, data, 0, 1);
        }

        private void tSMI_S_InqDB_Click(object sender, EventArgs e)
        {
            byte[] data = new byte[1];
            data[0] = 0x01;
            myport.SendCmd(0x02, 0xa4, data, 0, 1);
        }

        private void tSMI_S_CreatSimulationFile_Click(object sender, EventArgs e)
        {
            SimulationData.CreatSimulationFile();
        }

        private void tSMI_S_CreatSimulationFile2_Click(object sender, EventArgs e)
        {
            SimulationData.CreatSimulationFile_xls();
        }

        private void tSMI_AutoSelectLine_Click(object sender, EventArgs e)
        {
            tSMI_AutoSelectLine.Checked = !tSMI_AutoSelectLine.Checked;
            AutoSelectLine = tSMI_AutoSelectLine.Checked;
        }

        private void tSMI_D_RecPath_Click(object sender, EventArgs e)
        {
            string path = Application.StartupPath + @"\RecData";
            System.Diagnostics.Process.Start("explorer.exe", path);
        }

        private void tSMI_F_OpenXLS_Click(object sender, EventArgs e)
        {
            OpenFileDialog openf1 = new OpenFileDialog();
            openf1.Filter = "GPS XLS(.xls)|*.xls;*xlsx";
            openf1.Title = "Please select the XLS file!";
            openf1.Multiselect = false;
            openf1.InitialDirectory = LrnS.GetItem("currentDataBase");
            if (openf1.ShowDialog() == DialogResult.OK)
            {
                LrnS.SaveItem("currentDataBase", Path.GetDirectoryName(openf1.FileName));

                LoadMapFile(openf1.FileName);

                #region filepath
                string str = openf1.FileName;
                str = str.Substring(0, 1).ToUpper() + str.Substring(1);
                bubble_filepathArr(str, true);
                reNew_tSMI_F_LatestDB();
                #endregion

            }
        }

        private void tSMI_F_LatestDB1_Click(object sender, EventArgs e)
        {
            if (File.Exists(tSMI_F_LatestDB1.Text))
            {
                LoadMapFile(tSMI_F_LatestDB1.Text);
                bubble_filepathArr(tSMI_F_LatestDB1.Text, true);
            }
            else
            {
                bubble_filepathArr(tSMI_F_LatestDB1.Text, false);
                MessageBox.Show("File No Exit.");
            }
            reNew_tSMI_F_LatestDB();
            return;
        }

        private void tSMI_F_LatestDB2_Click(object sender, EventArgs e)
        {
            if (File.Exists(tSMI_F_LatestDB2.Text))
            {
                LoadMapFile(tSMI_F_LatestDB2.Text);
                bubble_filepathArr(tSMI_F_LatestDB2.Text, true);
            }
            else
            {
                bubble_filepathArr(tSMI_F_LatestDB2.Text, false);
                MessageBox.Show("File No Exit.");
            }
            reNew_tSMI_F_LatestDB();
            return;
        }

        private void tSMI_F_LatestDB3_Click(object sender, EventArgs e)
        {
            if (File.Exists(tSMI_F_LatestDB3.Text))
            {
                LoadMapFile(tSMI_F_LatestDB3.Text);
                bubble_filepathArr(tSMI_F_LatestDB3.Text, true);
            }
            else
            {
                bubble_filepathArr(tSMI_F_LatestDB3.Text, false);
                MessageBox.Show("File No Exit.");
            }
            reNew_tSMI_F_LatestDB();
            return;
        }

        private void tSMI_F_LatestDB4_Click(object sender, EventArgs e)
        {
            if (File.Exists(tSMI_F_LatestDB4.Text))
            {
                LoadMapFile(tSMI_F_LatestDB4.Text);
                bubble_filepathArr(tSMI_F_LatestDB4.Text, true);
            }
            else
            {
                bubble_filepathArr(tSMI_F_LatestDB4.Text, false);
                MessageBox.Show("File No Exit.");
            }
            reNew_tSMI_F_LatestDB();
            return;
        }

        private void tSMI_F_LatestDB5_Click(object sender, EventArgs e)
        {
            if (File.Exists(tSMI_F_LatestDB5.Text))
            {
                LoadMapFile(tSMI_F_LatestDB5.Text);
                bubble_filepathArr(tSMI_F_LatestDB5.Text, true);
            }
            else
            {
               bubble_filepathArr(tSMI_F_LatestDB5.Text, false);
                MessageBox.Show("File No Exit.");
            }
            reNew_tSMI_F_LatestDB();
            return;
        }

        private void tSMI_S_Start_Click(object sender, EventArgs e)
        {
            if (mydata.OpenTestFiles())
                TrainRun_Timer.Enabled = true;
        }

        private void tSMI_D_AppPath_Click(object sender, EventArgs e)
        {
            string path = Application.StartupPath;
            System.Diagnostics.Process.Start("explorer.exe", path);
        }

        private void tSMI_F_OpenGISFile_Click(object sender, EventArgs e)
        {
            if (groupBoxMap.Enabled == false)
            {
                MessageBox.Show("DataBase No Found");
                return;
            }
            gpsI.ReadInMDBPoint();
        }

        private void tSMI_F_OpenXlsInfoP_Click(object sender, EventArgs e)
        {
            if (groupBoxMap.Enabled == false)
            {
                MessageBox.Show("DataBase No Found");
                return;
            }
            gpsI.ReadInXLSPoint();
        }

        private void tSMI_StationName_Click(object sender, EventArgs e)
        {
            tSMI_StationName.Checked = !tSMI_StationName.Checked;
            gpsI.StationNameChecked = tSMI_StationName.Checked;
        }

        private void tSMI_AllRoad_Click(object sender, EventArgs e)
        {
            tSMI_AllRoad.Checked = !tSMI_AllRoad.Checked;
            gpsI.SelectAllRoad = tSMI_AllRoad.Checked;
        }

        private void tSMI_Connect_Click(object sender, EventArgs e)
        {
            tSMI_Connect.Checked = !tSMI_Connect.Checked;
            gpsI.SelectConnect = tSMI_Connect.Checked;
        }

        private void tSMI_Switch_Click(object sender, EventArgs e)
        {
            tSMI_Switch.Checked = !tSMI_Switch.Checked;
            gpsI.SelectSwitch = tSMI_Switch.Checked;
        }

        private void tSMI_Region_Click(object sender, EventArgs e)
        {
            tSMI_Region.Checked = !tSMI_Region.Checked;
            gpsI.SelectRegion = tSMI_Region.Checked;
        }

        private void tSMI_Scale_Click(object sender, EventArgs e)
        {
            tSMI_Scale.Checked = !tSMI_Scale.Checked;
            gpsI.SelectScale = tSMI_Scale.Checked;
        }

        private void tSMI_V_AutoShow_Click(object sender, EventArgs e)
        {
            tSMI_V_AutoShow.Checked = !tSMI_V_AutoShow.Checked;
        }

        private void tSMI_RoadSelect_SelectedIndexChanged(object sender, EventArgs e)
        {
            gpsI.FocusOnRoad(tSMI_RoadSelect.Text.ToString(),true);
        }

        private void tSMI_RoadSelect_TextUpdate(object sender, EventArgs e)
        {
            ReadAllRoad(tSMI_RoadSelect.Text.ToString());
            tSMI_RoadSelect.Select(tSMI_RoadSelect.Text.Length,0);
            Cursor = Cursors.Default;
            tSMI_RoadSelect.DroppedDown = true;
        }

        private void tSMI_RoadSelect_Click(object sender, EventArgs e)
        {
            ReadAllRoad("");
            tSMI_RoadSelect.Select(tSMI_RoadSelect.Text.Length, 0);
            Cursor = Cursors.Default;
            tSMI_RoadSelect.DroppedDown = true;
        }

        private void tSMI_RoadSelect_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue != 13)
                return;
            tSMI_IMAGE.HideDropDown();
        }

        private void tSMI_GIS_ValidateXLS_Click(object sender, EventArgs e)
        {
            OpenFileDialog openf1 = new OpenFileDialog();
            openf1.Filter = "GPS XLS(.xls)|*.xls";
            openf1.Title = "Please select the XLS file!";
            openf1.Multiselect = false;
            if (openf1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    DifferentStInXLS(openf1.FileName);
                }
                catch (Exception er)
                {
                    MessageBox.Show("validtation Error: " + er.Message.ToString());
                }
            }
        }

        private void tSMI_CreatDotGPS_Click(object sender, EventArgs e)
        {
            DotGPS myDotGPS = new DotGPS();
            myDotGPS.CreatDotGpsFile();
        }

        private void tSMI_CreatPhoneBook_Click(object sender, EventArgs e)
        {
            DotGPS myDotGPS = new DotGPS();
            myDotGPS.CreatPhoneBook();
        }

        private void tSMI_findPhones_Click(object sender, EventArgs e)
        {
            DotGPS myDotGPS = new DotGPS();
            myDotGPS.findPhones();
        }

        private void tSMI_xlsCheck_Click(object sender, EventArgs e)
        {
            try
            {
                XlsCheck disp = new XlsCheck();
                disp.t_Have_s();
            }
            catch (Exception er)
            {
                MessageBox.Show("dispatch Error: " + er.Message.ToString());
            }

        }

        private void tSMI_fileHaveCheck_Click(object sender, EventArgs e)
        {
            try
            {
                XlsCheck disp = new XlsCheck();
                disp.fine_Have_sA();
            }
            catch (Exception er)
            {
                MessageBox.Show("dispatch Error: " + er.Message.ToString());
            }
        }

        private void tSMI_lonlat_Click(object sender, EventArgs e)
        {
            try
            {
                XlsCheck disp = new XlsCheck();
                disp.XLSdimiToStd();
            }
            catch (Exception er)
            {
                MessageBox.Show("dispatch Error: " + er.Message.ToString());
            }
        }

        private void tSMI_creatRegion_Click(object sender, EventArgs e)
        {
            try
            {
                XlsCheck disp = new XlsCheck();
                disp.XLSCreatRegion();
            }
            catch (Exception er)
            {
                MessageBox.Show("dispatch Error: " + er.Message.ToString());
            }
        }



        private void TSMI_MissingPhone_Click(object sender, EventArgs e)
        {
            try
            {
                XlsCheck disp = new XlsCheck();
                disp.missingPhone();
            }
            catch (Exception er)
            {
               MessageBox.Show("dispatch Error: " + er.Message.ToString());
            }
        }

        private void tSMI_Stop_Click(object sender, EventArgs e)
        {
            if (mydata.IsStop)
            {
                mydata.IsStop = false;
                tSMI_Stop.Text = "暂停";
            }
            else
            {
                mydata.IsStop = true;
                tSMI_Stop.Text = "取消暂停";
            }
            
        }

        private void tSMI_SetTestPoint_Click(object sender, EventArgs e)
        {
            mydata.IsManual = !mydata.IsManual;
        }

        #region 记录数据
        private void tSMI_MulProcess_Click(object sender, EventArgs e)
        {
            try
            {
                RecData r1 = new RecData(tSMI_RP_AllST.Checked, tSMI_RP_FB.Checked,
                    tSMI_RP_ST.Checked, tSMI_RP_PH.Checked, tSMI_RP_RD.Checked);
                r1.AnalysisMulRecTxt();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void tSMI_RecDataProcess_Click(object sender, EventArgs e)
        {
            try
            {
                RecData r1 = new RecData(tSMI_RP_AllST.Checked, tSMI_RP_FB.Checked,
                    tSMI_RP_ST.Checked, tSMI_RP_PH.Checked, tSMI_RP_RD.Checked);
                r1.AnalysisOneRecTxt();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

        #endregion

        #region Functon Method
        private void bubble_filepathArr(string str,bool toAdd)
        {
            myFilePath[4] = "";
            for (int i = 0; i < 4; i++)
            {
                if (myFilePath[i] == str || (myFilePath[i] != "" && !File.Exists(myFilePath[i])))
                {
                    for (int j = i; j < 4; j++)
                    {
                        myFilePath[j] = myFilePath[j + 1];
                    }
                    i--;
                }
            }
            if (!toAdd)
                return;
            for (int i = 0; i < 4; i++)
                myFilePath[4 - i] = myFilePath[3 - i];
            myFilePath[0] = str;
            for (int i = 0; i < 5; i++)
                LrnS.SaveItem("latestDbPath" + i.ToString(), myFilePath[i]);
        }

        private void reNew_tSMI_F_LatestDB()
        {
            bool found = false;
            tSMI_F_LatestDB1.Visible = false;
            tSMI_F_LatestDB2.Visible = false;
            tSMI_F_LatestDB3.Visible = false;
            tSMI_F_LatestDB4.Visible = false;
            tSMI_F_LatestDB5.Visible = false;
            if (myFilePath[0] != "" && File.Exists(myFilePath[0]))
            {
                tSMI_F_LatestDB1.Text = myFilePath[0];
                tSMI_F_LatestDB1.Visible = true;
                found = true;
            }
            if (myFilePath[1] != "" && File.Exists(myFilePath[1]))
            {
                tSMI_F_LatestDB2.Text = myFilePath[1];
                tSMI_F_LatestDB2.Visible = true;
                found = true;
            }
            if (myFilePath[2] != "" && File.Exists(myFilePath[2]))
            {
                tSMI_F_LatestDB3.Text = myFilePath[2];
                tSMI_F_LatestDB3.Visible = true;
                found = true;
            }
            if (myFilePath[3] != "" && File.Exists(myFilePath[3]))
            {
                tSMI_F_LatestDB4.Text = myFilePath[3];
                tSMI_F_LatestDB4.Visible = true;
                found = true;
            }
            if (myFilePath[4] != "" && File.Exists(myFilePath[4]))
            {
                tSMI_F_LatestDB5.Text = myFilePath[4];
                tSMI_F_LatestDB5.Visible = true;
                found = true;
            }
            tSMI_F_LatestDB1.Invalidate();
            if (!found)
            {
                tSMI_F_LatestDB1.Text = "No File";
                tSMI_F_LatestDB1.Visible = true;
            }
        }

        private void ReadAllRoad(string s)
        {
            tSMI_RoadSelect.Items.Clear();
            string[] rd = gpsI.AllRoad(s);
            for (int i = 0; i < rd.Length; i++)
            {
                if (!tSMI_RoadSelect.Items.Contains(rd[i]))
                    tSMI_RoadSelect.Items.Add(rd[i]);
            }
        }

        private void ShowSetLineAuto(string linename)
        {
            if (myframe.LineArray.Count > 0)
            {
                AskLineForm f1 = new AskLineForm(linename);
                f1.Owner = this;
                f1.Show();
            }
        }

        private void Delay(int msec)//延时
        {
            int last_start;
            int timeLen = 0;

            labelState.Font = new Font("Arial", 100);
            this.labelState.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            last_start = Environment.TickCount;
            while (timeLen <= msec)
            {
                labelState.Text = ((msec - timeLen) / 1000 + 1).ToString();
                Application.DoEvents();
                timeLen = (Environment.TickCount - last_start);
            }
            labelState.Text = "";
            this.labelState.TextAlign = System.Drawing.ContentAlignment.TopLeft;
            labelState.Font = new Font("Arial", 9);
        }

        private void RecFrameHnadler()
        {
            string boxStr = "";
            string fileSaveStr = "";

            myframe.ReadIn(myport.RecFrame[myport.RecTail].rectext, myport.RecFrame[myport.RecTail].reclength);

            if (myframe.CMD == 0xa2)
                return;
            boxStr = myframe.FrameStr + myport.RecTail.ToString() + "\r\n" + myframe.CmdStr;
            fileSaveStr = myframe.RecStr;

            CMDBox.Text = boxStr;

            if (myframe.CMD == 0xa4)
            {
                labelState.Text = myframe.CmdStr;
            }

            #region selection Box
            if (myframe.CmdType == 0x02 && (myframe.CMD == 0x12 || myframe.CMD == 0x01))
            {
                string linename = (string)mydata.FileNames[mydata.FileIndex - 1];
                ShowSetLineAuto(linename);
            }
            #endregion

            #region Save fileSaveStr
            string path_dir = Application.StartupPath + "\\RecData\\";
            if (!Directory.Exists(path_dir))
                Directory.CreateDirectory(path_dir);

            using (FileStream fs1 = new FileStream(Application.StartupPath + @"\RecData\" + mydata.RecFileName, FileMode.OpenOrCreate))
            {
                TextWriter w1 = new StreamWriter(fs1, Encoding.Default);
                fs1.Seek(0, SeekOrigin.End);
                w1.WriteLine(fileSaveStr + " :" + (DateTime.Now.Ticks % 1000000000 / 1000000).ToString());
                w1.Close();
                fs1.Close();
            }
            #endregion
        }

        private void StopSimulation()
        {
            tSMI_V_AutoShow.Checked = false;
            TrainRun_Timer.Enabled = false;
            myport.SendCmd(0x02, 0xa3, null, 0, 0);
            tSMI_S_Start.Enabled = false;
            Delay(1000);
            mydata.Clear();
            tSMI_S_Start.Enabled = true;
            gpsI.Train_lon = 0;
            gpsI.Train_lat = 0;
        }

        private void SendVGpsData()
        {
            byte[] tmpbyte = new byte[100];
            string str1 = "$GPRMC,000225.027,V,2232.9535,N,11405.2331,E,0.00,0.00,060180,,,N*70";
            int i = Encoding.Default.GetBytes(str1, 0, str1.Length, tmpbyte, 0);
            tmpbyte[i] = 0x0d;
            tmpbyte[i] = 0x0a;
            myport.SendCmd(0x02, 0xa2, tmpbyte, 0, (uint)(i + 2));
        }

        private void DisplayMap()
        {
            #region Display RoadMap
            Graphics hh = this.pictureBox1.CreateGraphics();
            hh.DrawImage(gpsI.GPS_DB_IMG, new Point((pictureBox1.Size.Width - gpsI.ImgWidth) / 2, (pictureBox1.Size.Height - gpsI.ImgHeight) / 2));
            hh.Dispose();
            #endregion

            #region
            DisplayTrain(0, 0);
            #endregion
            return;
        }

        private void DisplayTrain(int lon,int lat)
        {
            int intlon = gpsI.Train_lon - gpsI.CenterLon;
            int intlat = gpsI.Train_lat - gpsI.CenterLat;
            intlon = intlon / gpsI.Divisor + pictureBox1.Size.Width / 2;
            intlat = pictureBox1.Size.Height / 2 - intlat / gpsI.Divisor;

            if (intlon > 0 && intlon < pictureBox1.Size.Width && intlat > 0 && intlat < pictureBox1.Size.Height)
            {
                Graphics hh = this.pictureBox1.CreateGraphics();
                hh.DrawImage(gpsI.Train_IMG, new Point(intlon + lon, intlat + lat));
                hh.Dispose();
            }
            if (tSMI_V_AutoShow.Checked)
            {
                if (intlon < pictureBox1.Size.Width / 5 * 2 || intlon > pictureBox1.Size.Width / 5 * 4 ||
                    intlat < pictureBox1.Size.Height / 5 * 2 || intlat > pictureBox1.Size.Height / 5 * 4)
                {
                    gpsI.CenterLon = (int)mydata.CurLon * 10;
                    gpsI.CenterLat = (int)mydata.CurLat * 10;
                    gpsI.CreatGPS_DB_IMG();
                }
            }
        }

        private void LoadMapFile(string path)
        {
            this.Cursor = Cursors.WaitCursor;
            gpsI.ReadInXLS(path);

            if (gpsI.CenterLat == 33000000 && gpsI.CenterLon == 110000000 && gpsI.Divisor == 50000)
            {
                string lon = LrnS.GetItem("CenterLonValueSaving").Trim();
                if (lon != "")
                    gpsI.CenterLon = int.Parse(lon);
                string lat = LrnS.GetItem("CenterLatValueSaving").Trim();
                if (lat != "")
                    gpsI.CenterLat = int.Parse(lat);
                string div = LrnS.GetItem("GPSImgDivisorSaving").Trim();
                if (div != "")
                    gpsI.Divisor = int.Parse(div);
            }

            pictureBox1.BackColor = Color.Pink;
            groupBoxMap.Enabled = true;

            gpsI.CreatGPS_DB_IMG();
            pictureBox1.Invalidate();

            this.Cursor = Cursors.Default;
        }

        private void toWriteInQieHuang(MYEXCEL.Excel.Worksheet xSheet1, DataSet resultdataset, int totalDataNumber)
        {
            string qieHuangName = "";
            for (int dataIndex = 0; dataIndex < totalDataNumber; dataIndex++)
            {
                qieHuangName = resultdataset.Tables["export"].Rows[dataIndex]["信息点名称"].ToString().Trim();
                if (qieHuangName.IndexOf("切换") > 0)
                {
                    int lastIndex = dataIndex, nextIndex = dataIndex;
                    if (lastIndex > 5)
                        lastIndex -= 5;
                    else
                        lastIndex = 0;

                    if (nextIndex < totalDataNumber - 5)
                        nextIndex += 5;
                    else
                        nextIndex = totalDataNumber - 1;

                    xSheet1.Cells[writeQieHuan, 1] = resultdataset.Tables["export"].Rows[dataIndex]["所属线路名称"].ToString().Trim();
                    xSheet1.Cells[writeQieHuan, 2] = qieHuangName;
                    xSheet1.Cells[writeQieHuan, 3] = resultdataset.Tables["export"].Rows[dataIndex]["经度"].ToString().Trim();
                    xSheet1.Cells[writeQieHuan, 4] = resultdataset.Tables["export"].Rows[dataIndex]["纬度"].ToString().Trim();
                    xSheet1.Cells[writeQieHuan, 5] = resultdataset.Tables["export"].Rows[lastIndex]["所属区段名称"].ToString().Trim();
                    xSheet1.Cells[writeQieHuan, 6] = resultdataset.Tables["export"].Rows[lastIndex]["工作模式"].ToString().Trim();
                    xSheet1.Cells[writeQieHuan, 7] = resultdataset.Tables["export"].Rows[nextIndex]["所属区段名称"].ToString().Trim();
                    xSheet1.Cells[writeQieHuan, 8] = resultdataset.Tables["export"].Rows[nextIndex]["工作模式"].ToString().Trim();
                    writeQieHuan++;
                }
            }
        }

        private void toWriteInDispatch(MYEXCEL.Excel.Worksheet xSheet1, DataSet resultdataset, int totalDataNumber)
        {
            string stationProperty;
            string lastMode = null, currMode = null;
            string lastDispatch = null, currDispatch = null, roadCode;
            for (int dataIndex = 0; dataIndex < totalDataNumber; dataIndex++)
            {
                stationProperty = resultdataset.Tables["export"].Rows[dataIndex]["信息点属性"].ToString().Trim();
                if (stationProperty != "11" && stationProperty != "12")
                    continue;
                roadCode = resultdataset.Tables["export"].Rows[dataIndex]["所属线路代码"].ToString().Trim();
                roadCode = roadCode.TrimEnd('D');
                roadCode = roadCode.TrimEnd('U');
                roadCode = roadCode.TrimEnd('S');
                roadCode = roadCode.TrimStart('L');

                lastMode = currMode;
                currMode = resultdataset.Tables["export"].Rows[dataIndex]["工作模式"].ToString().Trim();
                lastDispatch = currDispatch;
                currDispatch = resultdataset.Tables["export"].Rows[dataIndex]["所属区段名称"].ToString().Trim();
                if (lastDispatch != currDispatch || lastMode != currMode)
                {
                    xSheet1.Cells[writeDisRow, 1] = writeDisRow - 1;
                    xSheet1.Cells[writeDisRow, 2] = roadCode;
                    xSheet1.Cells[writeDisRow, 3] = resultdataset.Tables["export"].Rows[dataIndex]["所属线路名称"].ToString().Trim();
                    xSheet1.Cells[writeDisRow, 4] = currDispatch;
                    xSheet1.Cells[writeDisRow, 5] = currMode;
                    writeDisRow++;
                }
            }
        }

        private void toWriteInStation(MYEXCEL.Excel.Worksheet xSheet1, int roadIndex, DataSet resultdataset, int totalDataNumber)
        {
            int[] stationindex = new int[600];
            int stationNumber = 0;

            #region 查找所有车站
            string stationProperty, stationName;
            for (int i = 0; i < totalDataNumber; i++)
            {
                stationName = resultdataset.Tables["export"].Rows[i]["信息点名称"].ToString().Trim();
                stationProperty = resultdataset.Tables["export"].Rows[i]["信息点属性"].ToString().Trim();
                if (stationProperty == "11" || stationProperty == "12")
                {
                    if (stationName.EndsWith("信号机"))
                        continue;
                    if (stationNumber == 600)
                    {
                        MessageBox.Show("error1:To Many Station Found! ");
                        break;
                    }
                    stationindex[stationNumber] = i;
                    stationNumber++;
                }
            }
            #endregion

            int lastPost = 0, currPost = 0, postDistace;
            for (int stationCount = 0; stationCount < stationNumber; stationCount++)
            {
                #region 写入信息点
                if (stationCount > 0)
                {
                    lastPost = int.Parse(resultdataset.Tables["export"].Rows[stationindex[stationCount - 1]]["公里标"].ToString().Trim());
                    currPost = int.Parse(resultdataset.Tables["export"].Rows[stationindex[stationCount]]["公里标"].ToString().Trim());
                    postDistace = currPost - lastPost;


                    if (postDistace > 5000)
                    {
                        #region 前信息点
                        int fp_indexOffset = 1;
                        while (int.Parse(resultdataset.Tables["export"].Rows[stationindex[stationCount - 1] + fp_indexOffset]["公里标"].ToString().Trim()) < (lastPost + 1500)
                            || resultdataset.Tables["export"].Rows[stationindex[stationCount - 1] + fp_indexOffset]["经度"].ToString().Trim() == "0")
                        {
                            fp_indexOffset++;
                        }
                        int point1 = stationindex[stationCount - 1] + fp_indexOffset;
                        writeInAData(xSheet1, writeRow, resultdataset, point1, stationCount, 2, roadIndex);
                        writeRow++;
                        #endregion

                        #region 增加中间信息点（多个）
                        if (postDistace > 30000)
                        {
                            int mp_Number = postDistace / 30000;
                            int mp_Count = 1;
                            int mp_IndexOffset = 1;
                            int lengthUnit = postDistace / (mp_Number + 1);
                            while (mp_Count <= mp_Number)
                            {
                                while (int.Parse(resultdataset.Tables["export"].Rows[stationindex[stationCount - 1] + mp_IndexOffset]["公里标"].ToString().Trim()) < (lastPost + lengthUnit * mp_Count)
                                    || resultdataset.Tables["export"].Rows[stationindex[stationCount - 1] + mp_IndexOffset]["经度"].ToString().Trim() == "0")
                                {
                                    mp_IndexOffset++;
                                }
                                int mp_DataIndex = stationindex[stationCount - 1] + mp_IndexOffset;
                                writeInAData(xSheet1, writeRow, resultdataset, mp_DataIndex, stationCount, 1, roadIndex);
                                writeRow++;
                                mp_Count++;
                            }

                        }
                        #endregion

                        #region 后信息点
                        int lp_indexOffset = 1;
                        while (int.Parse(resultdataset.Tables["export"].Rows[stationindex[stationCount] - lp_indexOffset]["公里标"].ToString().Trim()) > (currPost - 1500)
                            || resultdataset.Tables["export"].Rows[stationindex[stationCount] - lp_indexOffset]["经度"].ToString().Trim() == "0")
                        {
                            lp_indexOffset++;
                        }
                        int point2 = stationindex[stationCount] - lp_indexOffset;
                        writeInAData(xSheet1, writeRow, resultdataset, point2, stationCount, 3, roadIndex);
                        writeRow++;
                        #endregion

                    }
                    else if (postDistace > 3000)
                    {
                        #region 中间信息点（一个）
                        int sp_indexOffset = 1;
                        int middlePost = (lastPost + currPost) / 2;
                        while (int.Parse(resultdataset.Tables["export"].Rows[stationindex[stationCount - 1] + sp_indexOffset]["公里标"].ToString().Trim()) < middlePost
                            || resultdataset.Tables["export"].Rows[stationindex[stationCount - 1] + sp_indexOffset]["经度"].ToString().Trim() == "0")
                        {
                            sp_indexOffset++;
                        }
                        int middleRow = stationindex[stationCount - 1] + sp_indexOffset;
                        writeInAData(xSheet1, writeRow, resultdataset, middleRow, stationCount, 4, roadIndex);
                        writeRow++;
                        #endregion
                    }
                }
                #endregion

                #region 写入车站
                if (stationCount != (stationNumber - 1))
                    writeInAData(xSheet1, writeRow, resultdataset, stationindex[stationCount], stationCount, 5, roadIndex);
                else
                    writeInAData(xSheet1, writeRow, resultdataset, stationindex[stationCount], stationCount, 6, roadIndex);
                writeRow++;
                #endregion
            }
            return;
        }

        private void writeInAData(MYEXCEL.Excel.Worksheet xSheet1, int excelRow, DataSet resultdataset, int mdbRow, int stationIndex, int dataType, int roadIndex)
        {
            string startIndex = tSMI_GIS_StationIndex.Text.Trim();
            xSheet1.Cells[excelRow, 1] = resultdataset.Tables["export"].Rows[mdbRow]["所属线路名称"].ToString().Trim();
            xSheet1.Cells[excelRow, 2] = resultdataset.Tables["export"].Rows[mdbRow]["所属区段名称"].ToString().Trim();
            xSheet1.Cells[excelRow, 3] = resultdataset.Tables["export"].Rows[mdbRow]["工作模式"].ToString().Trim();

            string stationName, stationPhone;
            int stationRange, stationProperty, nextStation1, nextStation2, stationCode;

            if (dataType == 5 || dataType == 6)
            {
                stationName = resultdataset.Tables["export"].Rows[mdbRow]["车站名称"].ToString().Trim();
                stationName = toStationName(stationName);

                stationCode = roadIndex * 1000 + int.Parse(startIndex) + stationIndex;

                stationPhone = resultdataset.Tables["export"].Rows[mdbRow]["车站电话号码"].ToString().Trim();
                if (stationPhone == "")
                    stationPhone = "0";

                stationProperty = 17;
                stationRange = 200;

                if (stationIndex > 0)
                    nextStation1 = roadIndex * 1000 + int.Parse(startIndex) + stationIndex - 1;
                else
                    nextStation1 = 0;

                if (dataType == 6)
                    nextStation2 = 0;
                else
                    nextStation2 = roadIndex * 1000 + int.Parse(startIndex) + stationIndex + 1;
            }
            else
            {
                stationName = "*";
                if (dataType == 1)
                    stationName = "**";
                stationCode = 0;
                stationPhone = "0";
                stationProperty = 21;
                stationRange = 50;
                nextStation1 = roadIndex * 1000 + int.Parse(startIndex) + stationIndex - 1;
                nextStation2 = roadIndex * 1000 + int.Parse(startIndex) + stationIndex;
            }

            xSheet1.Cells[excelRow, 4] = stationName;
            xSheet1.Cells[excelRow, 5] = stationCode;
            xSheet1.Cells[excelRow, 6] = stationPhone;
            xSheet1.Cells[excelRow, 7] = resultdataset.Tables["export"].Rows[mdbRow]["经度"].ToString().Trim();
            xSheet1.Cells[excelRow, 8] = resultdataset.Tables["export"].Rows[mdbRow]["纬度"].ToString().Trim();
            xSheet1.Cells[excelRow, 9] = stationProperty;
            xSheet1.Cells[excelRow, 10] = stationRange;
            xSheet1.Cells[excelRow, 11] = stationRange;
            xSheet1.Cells[excelRow, 12] = stationRange;
            xSheet1.Cells[excelRow, 13] = stationRange;
            xSheet1.Cells[excelRow, 14] = stationRange;
            xSheet1.Cells[excelRow, 15] = stationRange;
            xSheet1.Cells[excelRow, 16] = stationRange;
            xSheet1.Cells[excelRow, 17] = stationRange;
            xSheet1.Cells[excelRow, 18] = nextStation1;
            xSheet1.Cells[excelRow, 19] = nextStation2;
            xSheet1.Cells[excelRow, 20] = 0;
            xSheet1.Cells[excelRow, 21] = 0;
        }

        private string toStationName(string stationName)
        {
            if (stationName.IndexOf("车站") > 0)
                stationName = stationName.Remove(stationName.IndexOf("车站"));
            if (stationName.IndexOf("站") > 0)
                stationName = stationName.Remove(stationName.IndexOf("站"));
            if (stationName.IndexOf("线路") > 0)
                stationName = stationName.Remove(stationName.IndexOf("线路"));
            if (stationName.IndexOf("中心") > 0)
                stationName = stationName.Remove(stationName.IndexOf("中心"));

            return stationName;
        }

        private int Add0x10toCmdBuf(byte[] cmdBuf, int cmdLen, byte[] newCmdBuf)
        {
            int i = 0, j = 2;

            newCmdBuf[0] = 0x10;
            newCmdBuf[1] = 0x02;

            for (i = 0; i < cmdLen - 4; i++)
            {
                newCmdBuf[j++] = cmdBuf[i + 2];
                if (cmdBuf[i + 2] == 0x10)
                {
                    newCmdBuf[j++] = 0x10;
                }
            }
            newCmdBuf[j++] = 0x10;
            newCmdBuf[j++] = 0x03;
            return j;
        }

        private string Encoding_GetString(byte[] tmpbyte, int index, int len)
        {
            string str1 = "";
            try
            {
                str1 = Encoding.Default.GetString(tmpbyte, index, len);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            return str1;
        }

        private void SetGpsTXData(long longitude, long latitude)
        {
            int i, t;
            string s = "$GPRMC,";
            byte d, m, m1, m2;
            DateTime st = DateTime.UtcNow;
            byte[] tmpbyte = new byte[100];

            longitude = longitude * 6;
            latitude = latitude * 6;
            i = Encoding.Default.GetBytes(s, 0, s.Length, tmpbyte, 0);
            t = (int)(GF.HexToBCD((ulong)st.Hour, 2) & 0xff);
            tmpbyte[7] = (byte)((t / 16) + 0x30);
            tmpbyte[8] = (byte)((t & 0x0f) + 0x30);
            t = (int)(GF.HexToBCD((ulong)st.Minute, 2) & 0xff);
            tmpbyte[9] = (byte)((t / 16) + 0x30);
            tmpbyte[10] = (byte)((t & 0x0f) + 0x30);
            t = (int)(GF.HexToBCD((ulong)st.Second, 2) & 0xff);
            tmpbyte[11] = (byte)((t / 16) + 0x30);
            tmpbyte[12] = (byte)((t & 0x0f) + 0x30);
            tmpbyte[13] = (byte)('.');
            t = (int)(GF.HexToBCD((ulong)st.Millisecond, 2) & 0xff);
            tmpbyte[14] = (byte)((t / 16) + 0x30);
            tmpbyte[15] = (byte)((t & 0x0f) + 0x30);
            tmpbyte[16] = (byte)(',');
            tmpbyte[17] = (byte)('A');
            tmpbyte[18] = (byte)(',');

            d = (byte)(latitude / 600000);
            latitude = latitude % 600000;
            m = (byte)(latitude / 10000);
            latitude = latitude % 10000;
            m1 = (byte)(latitude / 100);
            m2 = (byte)(latitude % 100);
            tmpbyte[19] = (byte)((d / 10) + 0x30);
            tmpbyte[20] = (byte)((d % 10) + 0x30);
            tmpbyte[21] = (byte)((m / 10) + 0x30);
            tmpbyte[22] = (byte)((m % 10) + 0x30);
            tmpbyte[23] = (byte)('.');
            tmpbyte[24] = (byte)((m1 / 10) + 0x30);
            tmpbyte[25] = (byte)((m1 % 10) + 0x30);
            tmpbyte[26] = (byte)((m2 / 10) + 0x30);
            tmpbyte[27] = (byte)((m2 % 10) + 0x30);
            tmpbyte[28] = (byte)(',');
            tmpbyte[29] = (byte)('N');
            tmpbyte[30] = (byte)(',');

            d = (byte)(longitude / 600000);
            longitude = longitude % 600000;
            m = (byte)(longitude / 10000);
            longitude = longitude % 10000;
            m1 = (byte)(longitude / 100);
            m2 = (byte)(longitude % 100);
            tmpbyte[31] = (byte)((d / 100) + 0x30);
            d = (byte)(d % 100);
            tmpbyte[32] = (byte)((d / 10) + 0x30);
            tmpbyte[33] = (byte)((d % 10) + 0x30);
            tmpbyte[34] = (byte)((m / 10) + 0x30);
            tmpbyte[35] = (byte)((m % 10) + 0x30);
            tmpbyte[36] = (byte)('.');
            tmpbyte[37] = (byte)((m1 / 10) + 0x30);
            tmpbyte[38] = (byte)((m1 % 10) + 0x30);
            tmpbyte[39] = (byte)((m2 / 10) + 0x30);
            tmpbyte[40] = (byte)((m2 % 10) + 0x30);
            tmpbyte[41] = (byte)(',');
            tmpbyte[42] = (byte)('E');
            tmpbyte[43] = (byte)(',');
            //<0.0>~<1851.8>,
            tmpbyte[44] = (byte)('1');
            tmpbyte[45] = (byte)('0');
            tmpbyte[46] = (byte)('0');
            tmpbyte[47] = (byte)('0');
            tmpbyte[48] = (byte)('.');
            tmpbyte[49] = (byte)('5');
            tmpbyte[50] = (byte)(',');
            //<0.0>~<359.9>,
            tmpbyte[51] = (byte)('1');
            tmpbyte[52] = (byte)('2');
            tmpbyte[53] = (byte)('5');
            tmpbyte[54] = (byte)('.');
            tmpbyte[55] = (byte)('1');
            tmpbyte[56] = (byte)(',');

            t = (int)(GF.HexToBCD((ulong)st.Day, 2) & 0xff);
            tmpbyte[57] = (byte)((t / 16) + 0x30);
            tmpbyte[58] = (byte)((t & 0x0f) + 0x30);
            t = (int)(GF.HexToBCD((ulong)st.Month, 2) & 0xff);
            tmpbyte[59] = (byte)((t / 16) + 0x30);
            tmpbyte[60] = (byte)((t & 0x0f) + 0x30);
            t = (int)(GF.HexToBCD((ulong)st.Year, 2) & 0xff);
            tmpbyte[61] = (byte)((t / 16) + 0x30);
            tmpbyte[62] = (byte)((t & 0x0f) + 0x30);
            tmpbyte[63] = (byte)(',');
            tmpbyte[64] = (byte)('9');
            tmpbyte[65] = (byte)('0');
            tmpbyte[66] = (byte)('.');
            tmpbyte[67] = (byte)('6');
            tmpbyte[68] = (byte)(',');
            tmpbyte[69] = (byte)('E');
            tmpbyte[70] = (byte)(',');
            d = tmpbyte[1];
            for (i = 2; i < 71; i++)
                d = (byte)(d ^ tmpbyte[i]);
            tmpbyte[71] = (byte)('*');
            m = (byte)(d / 16);
            if (m > 9)
                tmpbyte[72] = (byte)(m + 0x37);
            else
                tmpbyte[72] = (byte)(m + 0x30);
            m = (byte)(d & 0x0f);
            if (m > 9)
                tmpbyte[73] = (byte)(m + 0x37);
            else
                tmpbyte[73] = (byte)(m + 0x30);
            tmpbyte[74] = 0x0d;
            tmpbyte[75] = 0x0a;

            myport.SendCmd(0x02, 0xa2, tmpbyte, 0, 76);
        }

        private void DifferentStInXLS(string path)
        {
            string path_dir = Application.StartupPath + "\\temp\\";
            if (!Directory.Exists(path_dir))
                Directory.CreateDirectory(path_dir);

            using (FileStream fs1 = new FileStream(path_dir + "different statons.txt", FileMode.OpenOrCreate))
            {
                TextWriter w1 = new StreamWriter(fs1, Encoding.Default);

                fs1.Seek(0, SeekOrigin.End);
                w1.WriteLine("\r\n" + DateTime.Now.ToString("yyyyMMddHHmm"));

                DataSet ds = GF.DsFromExcel(path);
                string StName1 = "";
                string StName2 = "";
                int rownumber = 0;
                if (!ds.Tables.Contains("车站$"))
                    return;
                while (rownumber<ds.Tables["车站$"].Rows.Count)
                {
                    if (!GF.IsEmpty(ds.Tables["车站$"].Rows[rownumber][0]))
                        rownumber++;
                    else
                        break;
                }
                for (int i = 0; i < rownumber; i++)
                {
                    if (ds.Tables["车站$"].Rows[i][8].ToString().Trim() == "17")
                    {
                        StName1 = ds.Tables["车站$"].Rows[i][3].ToString().Trim();
                        for (int j = 0; j < rownumber; j++)
                        {
                            StName2 = ds.Tables["车站$"].Rows[j][3].ToString().Trim();
                            if (StName1 == StName2 && i != j)
                                break;
                            if (j == rownumber - 1)
                            {
                                w1.WriteLine(StName1);
                            }
                        }
                    }
                }



                MessageBox.Show("验证完成!");

                w1.Close();
                fs1.Close();
            }
        }

        #endregion

        #region upgrade database

        Thread threadUpload;
        AutoResetEvent readEvent = new AutoResetEvent(false);


        #region whole Upgrade
        const int MTU = 200;
        private void ProcUpdateFirmware(object args)
        {
            string fileName = (string)args;

            #region//初始化进度条
            this.Invoke(new MethodInvoker(delegate
            {
                lbUpdateStatus.ForeColor = Color.Black;
                lbUpdateStatus.Text = "准备升级";
                pbUpdate.Value = 0;
            }));
            #endregion

            #region//读取程序文件
            if (File.Exists(fileName) == false)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "升级失败:文件不存在!";
                    lbUpdateStatus.ForeColor = Color.Red;
                    btUpload.Enabled = true;
                }));
                return;
            }
            byte[] fileData = File.ReadAllBytes(fileName);
            #endregion

            #region//计算传输的帧个数
            int frameCnt = fileData.Length / MTU;       //帧总数
            int leftLength = fileData.Length % MTU;     //最后一帧长度（MTU为帧长度）

            if (leftLength > 0)
            {
                frameCnt++;
            }
            #endregion

            #region//升级控制帧数据
            int maxFrameNum = frameCnt;             //最大帧序号（从1开始）=帧总数
            byte[] frameTx = new byte[6];
            frameTx[0] = (byte)(fileData.Length >> 24); //file length . MSB
            frameTx[1] = (byte)(fileData.Length >> 16); //file length . MSB
            frameTx[2] = (byte)(fileData.Length >> 8); //file length . MSB
            frameTx[3] = (byte)(fileData.Length >> 0); //file length . MSB
            frameTx[4] = (byte)(maxFrameNum >> 8);
            frameTx[5] = (byte)(maxFrameNum & 0xff);
            #endregion

            #region //upgrade 申请
            bool resetOK = false;
            for (int i = 0; i < 3; i++)
            {
                #region//(1)复位
                //myport.SendCmd(0x03, 0x4F, null, 0, 0);
                #endregion

                #region//(2)发送升级命令
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "发送升级命令";
                }));
                readEvent.Reset();
                myport.SendCmd(0x04, 0xC1, frameTx, 0, 6);
                for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
                {
                    readEvent.WaitOne(100);
                    if (myframe.CMD == 0xC2)
                    {
                        if (myframe.FrameByte[10] == 1)
                        {
                            resetOK = true;
                            break;
                        }
                        else
                        {
                            resetOK = false;
                            break;
                        }
                    }
                }
                #endregion

                #region reset ok
                if (resetOK == true)
                {
                   break;
                }
                #endregion
            }
            #region reset status error
            if (resetOK == false)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "升级失败:CPU复位失败!";
                    lbUpdateStatus.ForeColor = Color.Red;
                    btUpload.Enabled = true;
                }));
                return;
            }
            #endregion

            #endregion

            #region//(3)发送固件数据
            const int dataAttachCnt = 4;
            byte[] frameData = new byte[dataAttachCnt + MTU];
            int offset = 0;
            for (int i = 0; i < frameCnt; i++)
            {
                int txLen = MTU;
                if ((i == frameCnt - 1) && (leftLength > 0))
                {
                    txLen = leftLength;
                }

                bool sendOK = false;
                for (int j = 0; j < 10; j++)
                {
                    #region send package
                    this.Invoke(new MethodInvoker(delegate
                    {
                        if(j==0)
                            lbUpdateStatus.Text = String.Format("正在发送升级包：({0}/{1})",i + 1, frameCnt);
                        else
                            lbUpdateStatus.Text = String.Format("第{0}次重发升级包：({1}/{2})", j, i + 1, frameCnt);
                    }));

                    Array.Copy(fileData, offset, frameData, 4, txLen);
                    frameData[0] = (byte)((i + 1) >> 8); //帧序号
                    frameData[1] = (byte)((i + 1) & 0xff);
                    frameData[2] = (byte)((maxFrameNum) >> 8);
                    frameData[3] = (byte)((maxFrameNum) >> 0);
                    
                    int cmd = 0;

                    readEvent.Reset();
                    myport.SendCmd(0x04, 0xC3, frameData, 0, (uint)(txLen + dataAttachCnt));
                    #endregion

                    #region  acknowledge check
                    //Thread.Sleep(100);
                    for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
                    {
                        //Thread.Sleep(10);
                        readEvent.WaitOne(100);
                        cmd = myframe.CMD;
                        if (cmd == 0xC4 &&
                            myframe.FrameByte[10] == frameData[0] &&
                            myframe.FrameByte[11] == frameData[1] &&
                            myframe.FrameByte[12] == frameData[2] &&
                            myframe.FrameByte[13] == frameData[3])
                        {
                            if (myframe.FrameByte[14] == 1)
                            {
                                sendOK = true;
                                break;
                            }
                            else
                            {

                                sendOK = false;
                                break;
                            }
                        }
                    }
                    #endregion

                    #region send try status
                    if (sendOK)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            pbUpdate.Value = pbUpdate.Maximum * (i + 1) / frameCnt;
                        }));
                        offset += txLen;
                        break;//jump out and transmit next data frame.
                    }
                    else
                    {
                        #region error message
                        if (cmd == 0xC4 &&
                            myframe.FrameByte[10] == frameData[0] &&
                            myframe.FrameByte[11] == frameData[1] &&
                            myframe.FrameByte[12] == frameData[2] &&
                            myframe.FrameByte[13] == frameData[3])
                        {
                            this.Invoke(new MethodInvoker(delegate
                            {
                                lbUpdateStatus.ForeColor = Color.Red;
                                lbUpdateStatus.Text = String.Format("错误数据包应答：({0}，{1}，{2})",
                                                                       i + 1,
                                                                    myframe.FrameByte[14],
                                                                    myframe.FrameByte[15]);
                            }));
                        }
                        else
                        {
                            this.Invoke(new MethodInvoker(delegate
                            {
                                lbUpdateStatus.Text = " NO 数据包应答！";
                                lbUpdateStatus.ForeColor = Color.Purple;
                            }));
                        }
                        #endregion
                        Thread.Sleep(1000);
                        continue;//resend current data frame.
                    }
                    #endregion
                }

                #region package send status error
                if (sendOK == false)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        lbUpdateStatus.Text = "升级失败:发送升级数据包失败!";
                        lbUpdateStatus.ForeColor = Color.Red;
                        btUpload.Enabled = true;
                    }));
                    return;
                }
                #endregion

            }
            #endregion

            #region//(4)等待应用程序启动
            bool updateResetOK = false;
            for (int i = 0; i < 30; i++)
            {
                readEvent.Reset();
                myport.SendCmd(0x04, 0xC5, null, 0, 0);

                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = String.Format("查询升级状态({0}/{1})...", i + 1, 30);

                }));

                for (int sleepcnt = 0; sleepcnt < 10; sleepcnt++)
                {
                    readEvent.WaitOne(100);
                    int cmd = myframe.CMD;
                    if (cmd == 0xC6)
                    {
                        if (myframe.FrameByte[10] == 1)
                        {
                            updateResetOK = true;
                            break;
                        }
                        else
                        {

                            updateResetOK = false;
                            break;
                        }
                    }
                }

                if (updateResetOK)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        lbUpdateStatus.Text = "升级成功!";
                        lbUpdateStatus.ForeColor = Color.Green;
                        btUpload.Enabled = true;
                    }));
                    break;
                }
                Thread.Sleep(1000);

            }
            #endregion

            #region upgrade status
            if (updateResetOK == false)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "升级失败:查询升级状态失败!";
                    lbUpdateStatus.ForeColor = Color.Red;
                    btUpload.Enabled = true;
                }));
            }
            #endregion
        }

        private void tSMI_S_upgradeDB_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.InitialDirectory = LrnS.GetItem("upgradeDataBase");
                ofd.Filter = "Gps文件|*.GPS|BIN文件|*.bin|参数文件|*.txt";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    LrnS.SaveItem("upgradeDataBase", Path.GetDirectoryName(ofd.FileName));
                    threadUpload = new Thread(new ParameterizedThreadStart(ProcUpdateFirmware));
                    threadUpload.IsBackground = true;
                    threadUpload.Start(ofd.FileName);
                    btUpload.Enabled = false;
                }
            }
        }

        private void pbUpdate_Click(object sender, EventArgs e)
        {
            tSMI_S_upgradeDB_Click(null, null);
        }
        #endregion


        #region Increment Upgrade

        private void IncProcUpdateFirmware(object args)
        {
            string fileName = (string)args;
            byte[] stepcmd = new byte[6] { 0x80, 0x85, 0x00, 0x00, 0x0a, 0x94 };
            const int steptime = 200;


            const byte ResPonse_Update_Initial = 0x11;      // 0xD0;    //main-->GPS
            const byte Tx_Cmd_IncUp_ATTLEN = 0xD1;          //

            const byte F_S_Data_reQuest = 0x12;             //0xDD;     //GPS-->main

            const byte F_S_Data_Send = 0x13;                //0xD4;     //main-->GPS
            const byte Tx_Cmd_IncUp_ATTRACK = 0xD5;


            const byte F_I_Data_reQuest = 0x14;             //0xDC;     //GPS-->main

            const byte F_I_Data_Send = 0x15;                //0xD8;     //main-->GPS
            const byte Tx_Cmd_IncUp_MODULEDATA = 0xD9;


            const byte F_RePort_Data_Complete = 0x16;       //0xDE;     //GPS-->main
            const byte F_Report_Data_Complete_Ack = 0x17;               //main-->GPS

            const byte F_ReQuest_Local_Update = 0x18;                   //MMI-->server
            const byte F_ResPonse_Local_Update = 0x19;                  //server-->MMI
            const byte F_Report_Local_Update = 0x1A;                    // GPS-->main 
            const byte F_Report_Local_Update_Ack = 0x1B;                //main-->GPS

            const byte F_Inquiry_Local_DB_Status = 0x22;                //MMI-->GPS whether a new GPS is available for upgrade.
            const byte F_ResPonse_Local_DB_Status = 0x22;               //GPS-->MMI 
            const byte F_ReQuest_Start_Local_DB = 0x24;                 //MMI-->GPS   start using the new GPS database
            const byte F_ResPonse_Start_Local_DB = 0x25;                //GPS-->MMI

            #region 初始化进度条
            this.Invoke(new MethodInvoker(delegate
            {
                lbUpdateStatus.ForeColor = Color.Black;
                lbUpdateStatus.Text = "准备升级";
                pbUpdate.Value = 0;
            }));
            Thread.Sleep(steptime);
            #endregion

            #region 读取程序文件
            if (File.Exists(fileName) == false)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "升级失败:文件不存在!";
                    lbUpdateStatus.ForeColor = Color.Red;
                    btIncUpload.Enabled = true;
                }));
                return;
            }
            this.Invoke(new MethodInvoker(delegate
            {
                lbUpdateStatus.Text = "正在读取数据库文件";
            }));
            byte[] fileData = File.ReadAllBytes(fileName);
            Thread.Sleep(steptime);
            #endregion

            #region upgrade 发送摘要长度
            bool requestUpgrade = false;
            for (int i = 0; i < 3; i++)
            {
                #region 发送摘要长度
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "发送摘要文件的长度";
                    pbUpdate.Value = 0;
                }));
                readEvent.Reset();

                byte[] tabloidLen = new byte[53];

                tabloidLen[25] = 0;

                tabloidLen[45] = 0x00;
                tabloidLen[46] = 0x00;
                tabloidLen[47] = 0x04;
                tabloidLen[48] = 0x00;

                myport.SendCmd(0x1E, ResPonse_Update_Initial, tabloidLen, 0, 53);
                //Thread.Sleep(200);

                for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
                {
                    readEvent.WaitOne(100);
                    if (myframe.CMD == Tx_Cmd_IncUp_ATTLEN)
                    {
                        if (myframe.FrameByte[10] == 1)
                        {
                            requestUpgrade = true;
                            break;
                        }
                        else
                        {
                            requestUpgrade = false;
                            break;
                        }
                    }
                }
                #endregion

                #region requestUpgrade ok
                if (requestUpgrade == true)
                {
                    break;
                }
                #endregion
            }
            Thread.Sleep(200);

            #region requestUpgrade status
            if (requestUpgrade == false)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "升级失败:摘要长度发送失败";
                    lbUpdateStatus.ForeColor = Color.Red;
                    btUpload.Enabled = true;
                }));
                return;
            }
            else
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "发送摘要长度成功";
                    pbUpdate.Value = pbUpdate.Maximum;
                }));
            }
            Thread.Sleep(200);
            #endregion

            #endregion.

            #region step control 允许申请下载附加信息
            //stepcmd[5] = 0x91;
            //myport.SendCmd(0x04, 0xFF, stepcmd, 0, 6);
            //Thread.Sleep(100);
            #endregion

            #region 等待申请下载命令
            for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
            {
                if (!readEvent.WaitOne(100))
                {
                    if (sleepcnt == 29)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = "升级失败:没有收到申请文件头命令";
                            lbUpdateStatus.ForeColor = Color.Red;
                            btIncUpload.Enabled = true;
                        }));
                        return;
                    }
                    continue;
                }
                if (myframe.CMD == F_S_Data_reQuest)
                {
                    if (myframe.FrameByte[10 + 14] == 0 &&
                        myframe.FrameByte[10 + 15] == 0 &&
                        myframe.FrameByte[10 + 16] == 0 &&
                        myframe.FrameByte[10 + 17] == 0 &&
                        myframe.FrameByte[10 + 18] == 2 &&
                        myframe.FrameByte[10 + 19] == 0)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = "收到下载申请命令";
                            pbUpdate.Value = 0;
                        }));
                        break;
                    }
                    else
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = "升级失败:收到错误的申请文件头命令";
                            lbUpdateStatus.ForeColor = Color.Red;
                            btIncUpload.Enabled = true;
                        }));
                        return;
                    }
                }
            }
            #endregion

            #region upgrade 发送文件头
            bool HeadTrans = false;
            for (int i = 0; i < 3; i++)
            {
                #region 发送文件头信息
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "发送文件头信息";
                }));

                const int formlength = 11;
                int datalength = 512;
                int offset = 0;
                byte[] frameData = new byte[formlength  + datalength];

                Array.Copy(fileData, offset, frameData, formlength , datalength);

                frameData[0] = myframe.FrameByte[10 + 9];//last frame index.
                frameData[1] = myframe.FrameByte[10 + 10];
                frameData[2] = myframe.FrameByte[10 + 11];
                frameData[3] = myframe.FrameByte[10 + 12];

                frameData[4] = 0;//status

                frameData[5] = 0;//task id
                frameData[6] = 0;
                frameData[7] = 0;
                frameData[8] = 0;

                frameData[9] = (Byte)((datalength) >> 8);
                frameData[10] = (Byte)((datalength) >> 0);

                readEvent.Reset();
                myport.SendCmd(0x1E, F_S_Data_Send, frameData, 0, (uint)(formlength + datalength));

                for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
                {
                    readEvent.WaitOne(100);
                    if (myframe.CMD == Tx_Cmd_IncUp_ATTRACK)
                    {
                        if (myframe.FrameByte[10] == 1)
                        {
                            HeadTrans = true;
                            break;
                        }
                        else
                        {
                            HeadTrans = false;
                            break;
                        }
                    }
                }
                #endregion

                #region HeadTrans ok
                if (HeadTrans == true)
                {
                    break;
                }
                #endregion
            }
            #region reset status error
            Thread.Sleep(200);
            if (HeadTrans == false)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "升级失败:文件头发送失败";
                    lbUpdateStatus.ForeColor = Color.Red;
                    btUpload.Enabled = true;
                }));
                return;
            }
            else
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "发送文件头信息发送成功";
                    pbUpdate.Value = pbUpdate.Maximum;
                }));
            }
            Thread.Sleep(200);
            #endregion

            #endregion

            #region step control 允许写入文件头
            //Thread.Sleep(200);
            //stepcmd[5] = 0x92;
            //myport.SendCmd(0x04, 0xFF, stepcmd, 0, 6);
            //Thread.Sleep(2000);//等待格式化
            #endregion

            #region step control 允许申请下载附加信息
            //stepcmd[5] = 0x91;
            //myport.SendCmd(0x04, 0xFF, stepcmd, 0, 6);
            //Thread.Sleep(100);
            #endregion

            #region 等待申请摘要命令
            for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
            {
                if (!readEvent.WaitOne(100))
                {
                    if (sleepcnt == 29)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = "升级失败:没有收到申请摘要命令";
                            lbUpdateStatus.ForeColor = Color.Red;
                            btUpload.Enabled = true;
                        }));
                        return;
                    }
                    continue;
                }
                if (myframe.CMD == F_S_Data_reQuest)
                {
                    if (myframe.FrameByte[10 + 14] == 0 &&
                        myframe.FrameByte[10 + 15] == 0 &&
                        myframe.FrameByte[10 + 16] == 2 &&
                        myframe.FrameByte[10 + 17] == 0 &&
                        myframe.FrameByte[10 + 18] == 2 &&
                        myframe.FrameByte[10 + 19] == 0)
                    {
                        break;
                    }
                    else
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = "升级失败:收到错误的申请文件头命令";
                            lbUpdateStatus.ForeColor = Color.Red;
                            btUpload.Enabled = true;
                            pbUpdate.Value = 0;
                        }));
                        return;
                    }
                }
            }
            #endregion

            #region send tabloid
            bool tabloidTrans = false;
            for (int j = 0; j < 10; j++)
            {
                #region send tabloid
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = String.Format("第{0}次发送文件摘要", j);
                }));

                int cmd = 0;

                const int formlength = 11;
                int datalength = 512;
                int offset = 512;
                byte[] frameData = new byte[formlength + datalength];

                Array.Copy(fileData, offset, frameData, formlength, datalength);

                frameData[0] = myframe.FrameByte[10 + 9];//last frame index.
                frameData[1] = myframe.FrameByte[10 + 10];
                frameData[2] = myframe.FrameByte[10 + 11];
                frameData[3] = myframe.FrameByte[10 + 12];

                frameData[4] = 0;//status

                frameData[5] = 0;//task id
                frameData[6] = 0;
                frameData[7] = 0;
                frameData[8] = 0;

                frameData[9] = (Byte)((datalength) >> 8);
                frameData[10] = (Byte)((datalength) >> 0);

                readEvent.Reset();
                myport.SendCmd(0x1E, F_S_Data_Send, frameData, 0, (uint)(formlength + datalength));

                #endregion

                #region  acknowledge check
                //Thread.Sleep(100);
                for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
                {
                    //Thread.Sleep(10);
                    readEvent.WaitOne(100);
                    cmd = myframe.CMD;
                    if (cmd == Tx_Cmd_IncUp_ATTRACK)
                    {
                        if (myframe.FrameByte[10] == 1)
                        {
                            tabloidTrans = true;
                            break;
                        }
                        else
                        {

                            tabloidTrans = false;
                            break;
                        }
                    }
                }
                #endregion

                #region send try status
                if (tabloidTrans)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        //pbUpdate.Value = pbUpdate.Maximum * (i + 1) / frameCnt;
                    }));
                    break;//jump out and transmit next data frame.
                }
                else
                {
                    #region error message
                    if (cmd == Tx_Cmd_IncUp_ATTRACK)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.ForeColor = Color.Red;
                            lbUpdateStatus.Text = String.Format("错误数据包应答：({0}，{1}，{2})",
                                                                   Tx_Cmd_IncUp_ATTRACK,
                                                                myframe.FrameByte[10],
                                                                myframe.FrameByte[11]);
                        }));
                    }
                    else
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = " NO 数据包应答！";
                            lbUpdateStatus.ForeColor = Color.Purple;
                        }));
                    }
                    #endregion

                    Thread.Sleep(1000);
                    continue;//resend current data frame.
                }
                #endregion
            }

            #region package send status error
            if (tabloidTrans == false)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "升级失败:发送升级数据包失败!";
                    lbUpdateStatus.ForeColor = Color.Red;
                    btUpload.Enabled = true;
                }));
                return;
            }
            else
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lbUpdateStatus.Text = "发送摘要信息发送成功";
                    pbUpdate.Value = pbUpdate.Maximum;
                }));
            }
            #endregion



            #endregion

            #region step control 允许写入摘要
            //stepcmd[5] = 0x93;
            //myport.SendCmd(0x04, 0xFF, stepcmd, 0, 6);
            //Thread.Sleep(200);
            #endregion

            #region wait for module data apply
            int framecnt = 0;
            for (int waitcnt = 0; waitcnt < 100; waitcnt++)
            {
                #region step control 允许查表
                //stepcmd[5] = 0x95;
                //myport.SendCmd(0x04, 0xFF, stepcmd, 0, 6);
                //Thread.Sleep(steptime);
                #endregion

                #region finish check
                //bool finish = false;
                //for (int sleepcnt = 0; sleepcnt < 2; sleepcnt++)
                //{
                //    bool ack = readEvent.WaitOne(100);

                //    if (ack && myframe.CMD == F_RePort_Data_Complete)
                //    {
                //        finish = true;
                //    }
                //}
                //if (finish)
                //{
                //    this.Invoke(new MethodInvoker(delegate
                //    {
                //        lbUpdateStatus.Text = "模块数据下载完成";
                //        pbUpdate.Value = pbUpdate.Maximum;
                //    }));
                //    #region step control 是否启用新数据
                //    DialogResult startNewGps = MessageBox.Show("是否启用新下载的数据库");
                //    if (startNewGps == DialogResult.OK)
                //    {
                //        stepcmd[5] = 0x94;
                //        myport.SendCmd(0x04, F_ReQuest_Start_Local_DB, stepcmd, 0, 6);
                //        this.Invoke(new MethodInvoker(delegate
                //        {
                //            lbUpdateStatus.Text = "升级完成";
                //            btIncUpload.Enabled = true;
                //        }));
                //    }
                //    Thread.Sleep(2000);
                //    #endregion

                //    return;
                //}
                #endregion

                #region step control 允许申请下载
                //stepcmd[5] = 0x96;
                //myport.SendCmd(0x04, 0xFF, stepcmd, 0, 6);
                //Thread.Sleep(steptime);
                #endregion

                bool receivecmd;
                receivecmd = readEvent.WaitOne(100);

                if (receivecmd && myframe.CMD == F_I_Data_reQuest)
                {
                    waitcnt = 0;
                    framecnt++;

                    #region send module data
                    int offset =  myframe.FrameByte[10 + 17] + 
                                 (myframe.FrameByte[10 + 16] << 8) + 
                                 (myframe.FrameByte[10 + 15] << 16) + 
                                 (myframe.FrameByte[10 + 14] << 24);
                    int length = myframe.FrameByte[10 + 19] + (myframe.FrameByte[10 + 18] << 8);

                    this.Invoke(new MethodInvoker(delegate
                    {
                        lbUpdateStatus.Text = String.Format("下载{0}：(偏置：{1}；长度：{2}；总长：{3})", framecnt, offset, length, fileData.Length);
                        pbUpdate.Value = pbUpdate.Maximum * offset / fileData.Length;
                    }));

                    const int formlength = 11;
                    byte[] frameData = new byte[length + formlength];

                    Array.Copy(fileData, offset, frameData, formlength, length);

                    frameData[0] = myframe.FrameByte[10 + 9];//last frame index.
                    frameData[1] = myframe.FrameByte[10 + 10];
                    frameData[2] = myframe.FrameByte[10 + 11];
                    frameData[3] = myframe.FrameByte[10 + 12];

                    frameData[4] = 0;//status

                    frameData[5] = 0;//task id
                    frameData[6] = 0;
                    frameData[7] = 0;
                    frameData[8] = 0;

                    frameData[9] = (Byte)((length) >> 8);
                    frameData[10] = (Byte)((length) >> 0);


                    readEvent.Reset();
                    myport.SendCmd(0x1E, F_I_Data_Send, frameData, 0, (uint)length + formlength);

                    
                    //for (int sleepcnt = 0; sleepcnt < 30; sleepcnt++)
                    //{
                    //    bool ack = readEvent.WaitOne(100);

                    //    if (ack && myframe.CMD == Tx_Cmd_IncUp_MODULEDATA)
                    //    {
                    //        if (myframe.FrameByte[10] == 1)
                    //        {
                    //            tabloidTrans = true;
                    //            break;
                    //        }
                    //        else
                    //        {

                    //            tabloidTrans = false;
                    //            break;
                    //        }
                    //    }
                    //}
                    #endregion

                    #region step control 允许写入模块数据
                    //stepcmd[5] = 0x97;
                    //myport.SendCmd(0x04, 0xFF, stepcmd, 0, 6);
                    //Thread.Sleep(100);
                    #endregion
                }
                else if (receivecmd && myframe.CMD == F_RePort_Data_Complete)
                {
                    if (myframe.FrameByte[10+32] == 0)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = "下载完成，校验成功";
                            pbUpdate.Value = pbUpdate.Maximum;
                        }));

                        #region step control 是否启用新数据
                        DialogResult startNewGps = MessageBox.Show("是否启用新下载的数据库");
                        if (startNewGps == DialogResult.OK)
                        {
                            stepcmd[5] = 0x94;
                            myport.SendCmd(0x02, F_ReQuest_Start_Local_DB, stepcmd, 0, 6);
                            this.Invoke(new MethodInvoker(delegate
                            {
                                lbUpdateStatus.Text = "升级完成";
                                btIncUpload.Enabled = true;
                            }));
                        }
                        Thread.Sleep(2000);
                        #endregion

                        return;
                    }
                    else
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            lbUpdateStatus.Text = "下载完成，校验失败";
                            pbUpdate.Value = pbUpdate.Maximum;
                        }));
                        break;
                    }
                }
            }
            #endregion

            #region fail
            this.Invoke(new MethodInvoker(delegate
            {
                lbUpdateStatus.Text = "升级fail";
                btIncUpload.Enabled = true;
            }));
            #endregion

        }

        private void btIncUpload_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.InitialDirectory = LrnS.GetItem("IncUpgradeDataBase");
                ofd.Filter = "Gps文件|*.GPS|BIN文件|*.bin|参数文件|*.txt";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    LrnS.SaveItem("IncUpgradeDataBase", Path.GetDirectoryName(ofd.FileName));
                    threadUpload = new Thread(new ParameterizedThreadStart(IncProcUpdateFirmware));
                    threadUpload.IsBackground = true;
                    threadUpload.Start(ofd.FileName);
                    btIncUpload.Enabled = false;
                }
            }
        }

        #endregion

     


        #endregion












        //end************************************************************
    }
}
